Skip to content

Fix mypy arg-type errors in generated discriminated union encoders#175

Merged
darshkpatel merged 1 commit intomainfrom
fix-codegen-mypy-arg-type
Mar 5, 2026
Merged

Fix mypy arg-type errors in generated discriminated union encoders#175
darshkpatel merged 1 commit intomainfrom
fix-codegen-mypy-arg-type

Conversation

@darshkpatel
Copy link
Contributor

@darshkpatel darshkpatel commented Mar 5, 2026

Why

The codegen for discriminated union TypedDict encoders produces ternary chains like:

encode_Foo(x) if x["kind"] == "foo" else encode_Bar(x)

mypy can't narrow union types through these ternary conditions, so it flags every encoder call as receiving the wrong type (arg-type).

This broke the pid2 codegen CI when new discriminated union variants were added to a schema.

What changed

Use cast() to explicitly narrow the type to the correct variant after the discriminator check, instead of suppressing with # type: ignore[arg-type]. This preserves type safety in the generated code.

Before:

encode_Foo(x)  # type: ignore[arg-type]
if x["kind"] == "foo"
else encode_Bar(x)  # type: ignore[arg-type]

After:

encode_Foo(cast('Foo', x))
if x["kind"] == "foo"
else encode_Bar(cast('Bar', x))

Affects both the single-variant and multi-variant discriminator code paths.

Test plan

CI

The codegen for discriminated union TypedDict encoders generates a ternary
chain where mypy can't narrow the union type through key-based conditions.
Instead of suppressing with `# type: ignore[arg-type]`, use `cast()` to
explicitly narrow the type to the correct variant after the discriminator
check. This preserves type safety in the generated code.

Affects both the single-variant and multi-variant discriminator code paths.
@darshkpatel darshkpatel force-pushed the fix-codegen-mypy-arg-type branch from ef9a192 to 8c0a0f3 Compare March 5, 2026 19:38
@darshkpatel darshkpatel marked this pull request as ready for review March 5, 2026 19:53
@darshkpatel darshkpatel requested a review from a team as a code owner March 5, 2026 19:53
@darshkpatel darshkpatel requested review from daweifeng-replit and jackyzha0 and removed request for a team March 5, 2026 19:53
@darshkpatel darshkpatel merged commit 35ea72f into main Mar 5, 2026
3 checks passed
@darshkpatel darshkpatel deleted the fix-codegen-mypy-arg-type branch March 5, 2026 20:05
darshkpatel added a commit that referenced this pull request Mar 5, 2026
Why
===

Follow-up to #175. The discriminator field in a discriminated union may
be `NotRequired` in the TypedDict. Direct key access (`x["shapeType"]`)
triggers pyright's `reportTypedDictNotRequiredAccess` error.

This broke the pid2 codegen CI when the scribe schema added
discriminated union variants where the discriminator field is optional.

What changed
============

Use `x.get("key")` instead of `x["key"]` for discriminator checks in the
generated ternary chain. This is safe because a missing key returns
`None`, which won't match any discriminator value and falls through to
the next branch.

Test plan
=========

- All 64 tests pass
- Updated snapshot for `test_unknown_enum`
- Tested end-to-end against the pid2 schema from ai-infra — codegen,
mypy, and pyright all pass

~ written by Zerg 👾
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants